package com.macro.mall.portal.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.macro.mall.common.api.CommonResult;
import com.macro.mall.common.exception.Asserts;
import com.macro.mall.mapper.*;
import com.macro.mall.model.*;
import com.macro.mall.portal.dao.SmsCouponHistoryDao;
import com.macro.mall.portal.domain.CartPromotionItem;
import com.macro.mall.portal.domain.SmsCouponHistoryDetail;
import com.macro.mall.portal.dto.SmsCouponDto;
import com.macro.mall.portal.dto.SmsCouponGetDto;
import com.macro.mall.portal.service.UmsMemberCouponService;
import com.macro.mall.portal.service.UmsMemberService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 会员优惠券管理Service实现类
 * Created by macro on 2018/8/29.
 */
@Service
public class UmsMemberCouponServiceImpl implements UmsMemberCouponService {
    @Autowired
    private UmsMemberService memberService;
    @Autowired
    private SmsCouponMapper couponMapper;
    @Autowired
    private SmsCouponHistoryMapper couponHistoryMapper;
    @Autowired
    private SmsCouponHistoryDao couponHistoryDao;
    @Autowired
    private SmsCouponProductRelationMapper couponProductRelationMapper;
    @Autowired
    private SmsCouponProductCategoryRelationMapper couponProductCategoryRelationMapper;
    @Autowired
    private PmsProductMapper productMapper;

    @Override
    public int add(Long couponId) {
        UmsMember currentMember = memberService.getCurrentMember();
        //获取优惠券信息，判断数量
        SmsCoupon coupon = couponMapper.selectByPrimaryKey(couponId);
        if (coupon == null) {
            Asserts.fail("优惠券不存在");
        }
        if (coupon.getCount() <= 0) {
            Asserts.fail("优惠券已经领完了");
        }
        Date now = new Date();
        if(coupon.getEnableTime()!=null){
            if (now.before(coupon.getEnableTime())) {
                Asserts.fail("优惠券还没到领取时间");
            }
        }
        //判断用户领取的优惠券数量是否超过限制
        SmsCouponHistoryExample couponHistoryExample = new SmsCouponHistoryExample();
        couponHistoryExample.createCriteria().andCouponIdEqualTo(couponId).andMemberIdEqualTo(currentMember.getId());
        long count = couponHistoryMapper.countByExample(couponHistoryExample);
        if (count >= coupon.getPerLimit()) {
            Asserts.fail("您已经领取过该优惠券");
        }
        //生成领取优惠券历史
        SmsCouponHistory couponHistory = new SmsCouponHistory();
        couponHistory.setCouponId(couponId);
        couponHistory.setCouponCode(generateCouponCode(currentMember.getId()));
        couponHistory.setCreateTime(now);
        couponHistory.setMemberId(currentMember.getId());
        couponHistory.setMemberNickname(currentMember.getUsername());
        couponHistory.setStoreId(currentMember.getStoreId());
        couponHistory.setMemberUserName(currentMember.getUsername());
        //主动领取
        couponHistory.setGetType(1);
        //未使用
        couponHistory.setUseStatus(0);

        couponHistoryMapper.insert(couponHistory);
        //修改优惠券表的数量、领取数量
        coupon.setCount(coupon.getCount() - 1);
        coupon.setReceiveCount(coupon.getReceiveCount() == null ? 1 : coupon.getReceiveCount() + 1);
        if (coupon.getStoreId().equals(currentMember.getStoreId())) {
            return couponMapper.updateByPrimaryKey(coupon);
        } else {
            return -2;
        }
    }

    /**
     * 16位优惠码生成：时间戳后8位+4位随机数+用户id后4位
     */
    private String generateCouponCode(Long memberId) {
        StringBuilder sb = new StringBuilder();
        Long currentTimeMillis = System.currentTimeMillis();
        String timeMillisStr = currentTimeMillis.toString();
        sb.append(timeMillisStr.substring(timeMillisStr.length() - 8));
        for (int i = 0; i < 4; i++) {
            sb.append(new Random().nextInt(10));
        }
        String memberIdStr = memberId.toString();
        if (memberIdStr.length() <= 4) {
            sb.append(String.format("%04d", memberId));
        } else {
            sb.append(memberIdStr.substring(memberIdStr.length() - 4));
        }
        return sb.toString();
    }

    @Override
    public List<SmsCouponHistory> listHistory(Integer useStatus) {
        UmsMember currentMember = memberService.getCurrentMember();
        SmsCouponHistoryExample couponHistoryExample = new SmsCouponHistoryExample();
        SmsCouponHistoryExample.Criteria criteria = couponHistoryExample.createCriteria();
        criteria.andMemberIdEqualTo(currentMember.getId());
        if (useStatus != null) {
            criteria.andUseStatusEqualTo(useStatus);
        }
        return couponHistoryMapper.selectByExample(couponHistoryExample);
    }

    @Override
    public List<SmsCouponHistoryDetail> listCart(List<CartPromotionItem> cartItemList, Long memberId, Integer type) {
        Date now = new Date();
        //获取该用户所有优惠券
        List<SmsCouponHistoryDetail> allList = couponHistoryDao.getDetailList(memberId);
        //进商品详情页报错问题解决
        if (CollectionUtils.isEmpty(cartItemList) || CollectionUtils.isEmpty(allList)) {
            return new ArrayList<SmsCouponHistoryDetail>();
        }
        //根据优惠券使用类型来判断优惠券是否可用
        List<SmsCouponHistoryDetail> enableList = new ArrayList<>();
        List<SmsCouponHistoryDetail> disableList = new ArrayList<>();
        for (SmsCouponHistoryDetail couponHistoryDetail : allList) {
            if(couponHistoryDetail.getCoupon()!=null){
                Integer useType = couponHistoryDetail.getCoupon().getUseType();
                BigDecimal minPoint = couponHistoryDetail.getCoupon().getMinPoint();
                Date endTime = couponHistoryDetail.getCoupon().getEndTime();
                if (useType.equals(0)) {
                    //0->全场通用
                    //判断是否满足优惠起点
                    //计算购物车商品的总价
                    BigDecimal totalAmount = calcTotalAmount(cartItemList);
                    if (now.before(endTime) && totalAmount.subtract(minPoint).intValue() >= 0) {
                        enableList.add(couponHistoryDetail);
                    } else {
                        disableList.add(couponHistoryDetail);
                    }
                } else if (useType.equals(1)) {
                    //1->指定分类
                    //计算指定分类商品的总价
                    List<Long> productCategoryIds = new ArrayList<>();
                    for (SmsCouponProductCategoryRelation categoryRelation : couponHistoryDetail.getCategoryRelationList()) {
                        productCategoryIds.add(categoryRelation.getProductCategoryId());
                    }
                    BigDecimal totalAmount = calcTotalAmountByproductCategoryId(cartItemList, productCategoryIds);
                    if (now.before(endTime) && totalAmount.intValue() > 0 && totalAmount.subtract(minPoint).intValue() >= 0) {
                        enableList.add(couponHistoryDetail);
                    } else {
                        disableList.add(couponHistoryDetail);
                    }
                } else if (useType.equals(2)) {
                    //2->指定商品
                    //计算指定商品的总价
                    List<Long> productIds = new ArrayList<>();
                    for (SmsCouponProductRelation productRelation : couponHistoryDetail.getProductRelationList()) {
                        productIds.add(productRelation.getProductId());
                    }
                    BigDecimal totalAmount = calcTotalAmountByProductId(cartItemList, productIds);
                    if (now.before(endTime) && totalAmount.intValue() > 0 && totalAmount.subtract(minPoint).intValue() >= 0) {
                        enableList.add(couponHistoryDetail);
                    } else {
                        disableList.add(couponHistoryDetail);
                    }
                }
            }
        }
        if (type.equals(1)) {
            return enableList;
        } else {
            return disableList;
        }
    }

    @Override
    public List<SmsCouponGetDto> listByProduct(Long productId) {
        UmsMember currentMember = memberService.getCurrentMember();
        List<Long> allCouponIds = new ArrayList<>();
        //获取指定商品优惠券
        SmsCouponProductRelationExample cprExample = new SmsCouponProductRelationExample();
        cprExample.createCriteria().andProductIdEqualTo(productId);
        List<SmsCouponProductRelation> cprList = couponProductRelationMapper.selectByExample(cprExample);
        if (CollUtil.isNotEmpty(cprList)) {
            List<Long> couponIds = cprList.stream().map(SmsCouponProductRelation::getCouponId).collect(Collectors.toList());
            allCouponIds.addAll(couponIds);
        }
        //获取指定分类优惠券
        PmsProduct product = productMapper.selectByPrimaryKey(productId);
        SmsCouponProductCategoryRelationExample cpcrExample = new SmsCouponProductCategoryRelationExample();
        cpcrExample.createCriteria().andProductCategoryIdEqualTo(product.getProductCategoryId());
        List<SmsCouponProductCategoryRelation> cpcrList = couponProductCategoryRelationMapper.selectByExample(cpcrExample);
        if (CollUtil.isNotEmpty(cpcrList)) {
            List<Long> couponIds = cpcrList.stream().map(SmsCouponProductCategoryRelation::getCouponId).collect(Collectors.toList());
            allCouponIds.addAll(couponIds);
        }
        if (CollUtil.isEmpty(allCouponIds)) {
            return new ArrayList<>();
        }
        //所有优惠券
        SmsCouponExample couponExample = new SmsCouponExample();
        couponExample.createCriteria().andEndTimeGreaterThan(new Date())
                .andStartTimeLessThan(new Date())
                .andUseTypeEqualTo(0)
                .andCountGreaterThan(0);
        couponExample.or(couponExample.createCriteria()
                .andEndTimeGreaterThan(new Date())
                .andStartTimeLessThan(new Date())
                .andUseTypeNotEqualTo(0)
                .andCountGreaterThan(0)
                .andIdIn(allCouponIds));
        List<SmsCoupon> smsCoupons = couponMapper.selectByExample(couponExample);
        List<SmsCouponGetDto> result = new ArrayList<>();
        if(!CollectionUtils.isEmpty(smsCoupons)){
            for (SmsCoupon smsCoupon: smsCoupons  ) {
                SmsCouponHistoryExample example = new SmsCouponHistoryExample();
                example.createCriteria().andCouponIdEqualTo(smsCoupon.getId()).andMemberIdEqualTo(currentMember.getId());
                List<SmsCouponHistory> smsCouponHistories = couponHistoryMapper.selectByExample(example);
                SmsCouponGetDto dto = new SmsCouponGetDto();
                BeanUtils.copyProperties(smsCoupon,dto);
                if(!CollectionUtils.isEmpty(smsCouponHistories)){
                    dto.setGetType(0);
                }else{
                    dto.setGetType(1);
                }
                result.add(dto);
            }
        }
        return result;
    }

    @Override
    public SmsCouponDto list(Integer useStatus, Integer type) {
        UmsMember member = memberService.getCurrentMember();
        List<SmsCoupon> couponList = couponHistoryDao.getCouponList(member.getId(), useStatus);
        List<SmsCoupon> couponResult = new ArrayList<>();
        if (!CollectionUtils.isEmpty(couponList)) {
            if (useStatus.equals(0) && type != null && type.equals(0)) {
                //下单页面，给优惠券去重
                ArrayList<SmsCoupon> collect = couponList.stream().collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(
                                Comparator.comparing(
                                        SmsCoupon::getId))), ArrayList::new));
                couponResult.addAll(collect);
            }else {
                couponResult.addAll(couponList);
            }
        }
        List<SmsCoupon> unusedList = couponHistoryDao.getCouponList(member.getId(), 0);
        List<SmsCoupon> usedList = couponHistoryDao.getCouponList(member.getId(), 1);
        List<SmsCoupon> expiredList = couponHistoryDao.getCouponList(member.getId(), 2);
        Map<String,Integer> count = new HashMap<>();
        count.put("unused",unusedList.size());
        count.put("used",usedList.size());
        count.put("expired",expiredList.size());
        SmsCouponDto result = new SmsCouponDto();
        result.setCount(count);
        if(!CollectionUtils.isEmpty(couponResult)){
            result.setList(couponResult);
            result.setType(useStatus);
        }
        return result;
    }

    private BigDecimal calcTotalAmount(List<CartPromotionItem> cartItemList) {
        BigDecimal total = new BigDecimal("0");
        for (CartPromotionItem item : cartItemList) {
            BigDecimal realPrice = item.getPrice().subtract(item.getReduceAmount());
            total = total.add(realPrice.multiply(new BigDecimal(item.getQuantity())));
        }
        return total;
    }

    private BigDecimal calcTotalAmountByproductCategoryId(List<CartPromotionItem> cartItemList, List<Long> productCategoryIds) {
        BigDecimal total = new BigDecimal("0");
        for (CartPromotionItem item : cartItemList) {
            if (productCategoryIds.contains(item.getProductCategoryId())) {
                BigDecimal realPrice = item.getPrice().subtract(item.getReduceAmount());
                total = total.add(realPrice.multiply(new BigDecimal(item.getQuantity())));
            }
        }
        return total;
    }

    private BigDecimal calcTotalAmountByProductId(List<CartPromotionItem> cartItemList, List<Long> productIds) {
        BigDecimal total = new BigDecimal("0");
        for (CartPromotionItem item : cartItemList) {
            if (productIds.contains(item.getProductId())) {
                BigDecimal realPrice = item.getPrice().subtract(item.getReduceAmount());
                total = total.add(realPrice.multiply(new BigDecimal(item.getQuantity())));
            }
        }
        return total;
    }

}
